<?php
namespace wanghua\general_utility_tools_php\gpt\chat;

use wanghua\general_utility_tools_php\phpmailer\Exception;

/**
 * 阿里云百炼多模态chat
 *
 * 单模态请使用ChatGPT.php
 *
 * Class AliCloudMultiChatGPT
 * @package wanghua\general_utility_tools_php\gpt\chat
 */
class AliCloudChatGPT extends BaseChat
{
    public $url = '';
    public $apiKey = '';
    public $model = '';
    private $messages = [];
    public $post_msg_body;

    public function __construct()
    {
        //调用父级
        parent::__construct();
    }

    /**
     * desc：定制个性
     * author：wh
     * @param array $customize
     */
    function setCustomize($customize = [])
    {
        if ($customize) {
            foreach ($customize as $item) {
                $this->messages[] = $item;
            }
        }
    }
    /**
     * desc：定制个性(多模态)
     * author：wh
     * @param array $customize
     */
    function setCustomizeMulti($customize = [])
    {
        if ($customize) {
            foreach ($customize as $item) {
                $this->messages[] = $item;
            }
        }
    }

    function setBefore($describe = [])
    {
        if ($describe) {
            foreach ($describe as $item) {
                $this->messages[] = $item;
            }
        }
    }

    function setAfter($describe = [])
    {
        if ($describe) {
            foreach ($describe as $item) {
                $this->messages[] = $item;
            }
        }
    }

    private function check()
    {
        if (empty($this->url) || empty($this->apiKey) || empty($this->model)) {
            throw new Exception('PARAMS ERROR');
        }
    }

    function chat($question = '', $config = [], &$answer_json_arr)
    {
        $answer = '';
        $this->curlPostChat($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) {
            $answer_json_arr[] = $data;
            $answer .= $data;
            echo $data;
            ob_flush();
            flush();
            return strlen($data);
        });
        return $answer;
    }

    function returnAnswer($question = '', $config = [], &$answer_json_arr)
    {
        $answer = '';
        $this->curlPostChat($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) {
            $answer_json_arr[] = $data;
            $answer .= $data;
            return strlen($data);
        });
        return $answer;
    }

    private function curlPostChat($question = '', $config = [], $callback)
    {
        $url = $this->url;
        $apiKey = $this->apiKey;
        $model = $this->model;
        $headers = ["Authorization: Bearer $apiKey", 'Accept: application/json', 'Content-Type: application/json',];
        $post_msg_body = ["model" => $model, 'stream' => true, 'chatId'=>$this->chatId];
        if ($config) {
            foreach ($config as $key => $val) {
                $post_msg_body[$key] = $val;
            }
        }
        if ($question) {
            $this->messages[] = ["role" => "user", "content" => $question];
        }
        $post_msg_body['messages'] = $this->messages;
        $this->post_msg_body = $post_msg_body;
        $postData = json_encode($post_msg_body);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback);
        curl_exec($ch);
    }



    /**
     * desc：多模态场景chat（如多图多轮对话）
     * author：wh
     * @param $images
     * @param $text
     * @return mixed
     * @throws \Exception
     */
    function generateMultimodalContent($images, $text)
    {
        $url = $this->url;
        $apiKey = $this->apiKey;
        $model = $this->model;
        $messages = [
            [
                'role' => 'user',
                'content' => array_map(function ($image) {
                    return ['image' => $image];
                }, $images),
            ],
        ];

        if (!empty($text)) {
            $messages[0]['content'][] = ['text' => $text];
        }

        $data = [
            'model' => $model,
            'input' => [
                'messages' => $messages,
            ],
        ];

        $options = [
            'http' => [
                'header' => "Authorization: Bearer $apiKey\r\n" .
                    "Content-Type: application/json\r\n",
                'method' => 'POST',
                'content' => json_encode($data),
            ],
        ];

        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);

        if ($result === FALSE) {
            throw new \Exception('Failed to fetch data from API');
        }

        return json_decode($result, true);
    }
}